home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 May / maximum-cd-2009-05.iso / DiscContents / XBMC_for_Windows-8.10.exe / plugins / Programs / SVN Repo Installer / installerAPI / xbmcplugin_downloader.py < prev    next >
Encoding:
Python Source  |  2008-10-20  |  7.2 KB  |  176 lines

  1. """
  2. Update module
  3.  
  4. Nuka1195
  5. """
  6.  
  7. # main imports
  8. import sys
  9. import os
  10. import xbmc
  11. import xbmcgui
  12. import xbmcplugin
  13.  
  14. import urllib
  15. import re
  16. from xml.sax.saxutils import unescape
  17.  
  18.  
  19. class Parser:
  20.     """ Parser Class: grabs all tag versions and urls """
  21.     # regexpressions
  22.     revision_regex = re.compile( '<h2>Revision ([0-9]*): ([^<]*)</h2>' )
  23.     asset_regex = re.compile( '<li><a href="([^"]*)">([^"]*)</a></li>' )
  24.  
  25.     def __init__( self, htmlSource ):
  26.         # set our initial status
  27.         self.dict = { "status": "fail", "revision": 0, "assets": [], "url": "" }
  28.         # fetch revision number
  29.         self._fetch_revision( htmlSource )
  30.         # if we were successful, fetch assets
  31.         if ( self.dict[ "revision" ] != 0 ):
  32.             self._fetch_assets( htmlSource )
  33.  
  34.     def _fetch_revision( self, htmlSource ):
  35.         try:
  36.             # parse revision and current dir level
  37.             revision, url = self.revision_regex.findall( htmlSource )[ 0 ]
  38.             # we succeeded :), set our info
  39.             self.dict[ "url" ] = url
  40.             self.dict[ "revision" ] = int( revision )
  41.         except:
  42.             pass
  43.  
  44.     def _fetch_assets( self, htmlSource ):
  45.         try:
  46.             assets = self.asset_regex.findall( htmlSource )
  47.             if ( len( assets ) ):
  48.                 for asset in assets:
  49.                     if ( asset[ 0 ] != "../" ):
  50.                         self.dict[ "assets" ] += [ unescape( asset[ 0 ] ) ]
  51.                 self.dict[ "status" ] = "ok"
  52.         except:
  53.             pass
  54.  
  55.  
  56. class _Info:
  57.     def __init__( self, *args, **kwargs ):
  58.         self.__dict__.update( kwargs )
  59.  
  60.  
  61. class Main:
  62.     def __init__( self ):
  63.         self.dialog = xbmcgui.DialogProgress()
  64.         # get the repository info
  65.         self._get_repo_info()
  66.         # parse sys.argv for our current url
  67.         self._parse_argv()
  68.         # create the script/plugin/skin title
  69.         self.title = self.args.download_url.split( "/" )[ -2 ].replace( "%20", " " )
  70.         # get the list
  71.         self._download_item()
  72.  
  73.     def _get_repo_info( self ):
  74.         # path to info file
  75.         repopath = os.path.join( os.getcwd(), "resources", "repositories", xbmcplugin.getSetting( "repository" ), "repo.xml" )
  76.         try:
  77.             # grab a file object
  78.             fileobject = open( repopath, "r" )
  79.             # read the info
  80.             info = fileobject.read()
  81.             # close the file object
  82.             fileobject.close()
  83.             # repo's base url
  84.             self.REPO_URL = re.findall( '<url>([^<]+)</url>', info )[ 0 ]
  85.         except:
  86.             # oops print error message
  87.             print "ERROR: %s::%s (%d) - %s" % ( self.__class__.__name__, sys.exc_info()[ 2 ].tb_frame.f_code.co_name, sys.exc_info()[ 2 ].tb_lineno, sys.exc_info()[ 1 ], )
  88.  
  89.     def _parse_argv( self ):
  90.         # call _Info() with our formatted argv to create the self.args object
  91.         exec "self.args = _Info(%s)" % ( sys.argv[ 2 ][ 1 : ].replace( "&", ", " ).replace( "\\u0027", "'" ).replace( "\\u0022", '"' ).replace( "\\u0026", "&" ), )
  92.         self.args.download_url = urllib.unquote_plus( self.args.download_url )
  93.  
  94.     def _download_item( self ):
  95.         try:
  96.             if ( xbmcgui.Dialog().yesno( self.title, xbmc.getLocalizedString( 30000 ), "", "", xbmc.getLocalizedString( 30020 ), xbmc.getLocalizedString( 30021 ) ) ):
  97.                 self.dialog.create( self.title, xbmc.getLocalizedString( 30002 ), xbmc.getLocalizedString( 30003 ) )
  98.                 asset_files = []
  99.                 folders = [ self.args.download_url ]
  100.                 while folders:
  101.                     try:
  102.                         htmlsource = self._get_html_source( self.REPO_URL + folders[ 0 ] )
  103.                         if ( not htmlsource ): raise
  104.                         items = self._parse_html_source( htmlsource )
  105.                         if ( not items or items[ "status" ] == "fail" ): raise
  106.                         files, dirs = self._parse_items( items )
  107.                         for file in files:
  108.                             asset_files.append( "%s/%s" % ( items[ "url" ], file, ) )
  109.                         for folder in dirs:
  110.                             folders.append( folders[ 0 ] + folder )
  111.                         folders = folders[ 1 : ]
  112.                     except:
  113.                         folders = []
  114.                 self._get_files( asset_files )
  115.         except:
  116.             # oops print error message
  117.             print "ERROR: %s::%s (%d) - %s" % ( self.__class__.__name__, sys.exc_info()[ 2 ].tb_frame.f_code.co_name, sys.exc_info()[ 2 ].tb_lineno, sys.exc_info()[ 1 ], )
  118.             self.dialog.close()
  119.             xbmcgui.Dialog().ok( self.title, xbmc.getLocalizedString( 30030 ) )
  120.         
  121.     def _get_files( self, asset_files ):
  122.         """ fetch the files """
  123.         try:
  124.             finished_path = ""
  125.             for cnt, url in enumerate( asset_files ):
  126.                 items = os.path.split( url )
  127.                 # TODO: Change this to U: for other than xbox
  128.                 drive = xbmc.translatePath( ( "U:\\%s" % self.args.install, "Q:\\%s" % self.args.install, )[ os.environ.get( "OS", "xbox" ) == "xbox" ] )
  129.                 path = os.path.join( drive, os.path.sep.join( items[ 0 ].split( "/" )[ self.args.ioffset : ] ).replace( "%20", " " ) )
  130.                 if ( not finished_path ): finished_path = path
  131.                 file = items[ 1 ].replace( "%20", " " )
  132.                 pct = int( ( float( cnt ) / len( asset_files ) ) * 100 )
  133.                 self.dialog.update( pct, "%s %s" % ( xbmc.getLocalizedString( 30005 ), url, ), "%s %s" % ( xbmc.getLocalizedString( 30006 ), path, ), "%s %s" % ( xbmc.getLocalizedString( 30007 ), file, ) )
  134.                 if ( self.dialog.iscanceled() ): raise
  135.                 if ( not os.path.isdir( path ) ): os.makedirs( path )
  136.                 url = self.REPO_URL + url
  137.                 fpath = os.path.join( path, file )
  138.                 urllib.urlretrieve( url.replace( " ", "%20" ), fpath )
  139.         except:
  140.             # oops print error message
  141.             print "ERROR: %s::%s (%d) - %s" % ( self.__class__.__name__, sys.exc_info()[ 2 ].tb_frame.f_code.co_name, sys.exc_info()[ 2 ].tb_lineno, sys.exc_info()[ 1 ], )
  142.             raise
  143.         else:
  144.             self.dialog.close()
  145.             xbmcgui.Dialog().ok( self.title, xbmc.getLocalizedString( 30008 ), finished_path )
  146.             
  147.     def _get_html_source( self, url ):
  148.         try:
  149.             sock = urllib.urlopen( url )
  150.             htmlsource = sock.read()
  151.             sock.close()
  152.             return htmlsource
  153.         except:
  154.             return ""
  155.  
  156.     def _parse_html_source( self, htmlsource ):
  157.         """ parse html source for tagged version and url """
  158.         try:
  159.             parser = Parser( htmlsource )
  160.             #parser.feed( htmlsource )
  161.             #parser.close()
  162.             return parser.dict
  163.         except:
  164.             return {}
  165.             
  166.     def _parse_items( self, items ):
  167.         """ separates files and folders """
  168.         folders = []
  169.         files = []
  170.         for item in items[ "assets" ]:
  171.             if ( item.endswith( "/" ) ):
  172.                 folders.append( item )
  173.             else:
  174.                 files.append( item )
  175.         return files, folders
  176.